package manager.analysis;

import javax.naming.InitialContext;
import javax.naming.NamingException;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;

import store.hibernate.Users;
import store.hibernate.Ws;
import store.hibernate.WsOperazione;

import manager.data.RawDataObject;
import static manager.utility.StaticFields.OUTBOUND;

public class SemanticControl implements Validation {
	
	private SessionFactory factory;
	
	public SemanticControl(){
		InitialContext ctx;
		try {
			ctx = new InitialContext();
		factory = (SessionFactory)ctx.lookup("java:/hibernate/SessionFactory");
		} catch (NamingException e) {
			e.printStackTrace();
		} 
	}

	public boolean validate(RawDataObject dpo) {
		boolean ok=directionControl(dpo.getDirection(), dpo.getKeyInbound()) &&
					userControl(dpo)	&&
					wsControl(dpo)		&&
					operationControl(dpo) &&
					eventControl(dpo.getKey());
		
		System.out.println("SemanticControl: "+ok);
		return ok;
	}

	private boolean eventControl(byte[] key) {
		Session session = factory.openSession();
		Query query = session.createQuery("select count(*) from Evento e where e.idE like ?");
		query.setBinary(0, key);
		query.setMaxResults(1);
		long num = (Long) query.uniqueResult();
		if (session.isOpen()) 
			session.close(); 
		if(num==1)
			return false;
		return true;
	}

	private boolean operationControl(RawDataObject dpo) {
		if(dpo.getWSObject()==null)
			return false;
		Session session = factory.openSession();
		Query query = session.createQuery("from WsOperazione wo where wo.ws like ? AND wo.nome like ?");
		query.setLong(0, dpo.getWSObject().getIdWs());
		query.setString(1, dpo.getOperation());
		query.setMaxResults(1);
		Object ob = query.uniqueResult();
		if (session.isOpen()) 
	          session.close(); 
		if(ob==null)
			return false;

		WsOperazione operationObject = (WsOperazione)ob;
		//System.out.println("IDOperation: "+num);
		dpo.setOperationObject(operationObject);
		return true;
	}

	private boolean wsControl(RawDataObject dpo) {
		Session session = factory.openSession();
		Query query = session.createQuery("from Ws w where w.nome like ? AND w.wsdlUrl like ? AND w.namespace like ?");
		query.setString(0, dpo.getWSName());
		query.setString(1, dpo.getWSDLURL());
		query.setString(2, dpo.getWSNamespace());
		query.setMaxResults(1);
		Object ob = query.uniqueResult();
		if (session.isOpen()) 
	          session.close(); 
		if(ob==null)
			return false;

		Ws wsObject = (Ws)ob;
		//System.out.println("IDWS: "+num);
		dpo.setWSObject(wsObject);
		return true;
	}

	private boolean userControl(RawDataObject dpo) {
		Session session = factory.openSession();
		Query query = session.createQuery("from Users u where u.username like ? AND u.password like ?");
		query.setString(0, dpo.getUsername());
		query.setString(1, dpo.getPassword());
		query.setMaxResults(1);
		Object ob = query.uniqueResult();
		if (session.isOpen()) 
	          session.close(); 
		if(ob==null)
			return false;

		Users userObject = (Users)ob;
		//System.out.println("IDUser: "+num);
		dpo.setUserObject(userObject);
		return true;
	}

	private boolean directionControl(char direction, byte[] keyInbound) {
		if(direction==OUTBOUND){
			if(keyInbound==null)
				return false;
			Session session = factory.openSession();
			Query query = session.createQuery("select count(*) from Evento e where e.idE like ?");
			query.setBinary(0, keyInbound);
			query.setMaxResults(1);
			long num = (Long) query.uniqueResult();
			if (session.isOpen()) 
				session.close(); 
			if(num!=1)
				return false;
		}
		return true;

	}

}
